import { BoxGeometry, Mesh, MeshBasicMaterial, MeshDepthMaterial, 
  MultiplyBlending, PerspectiveCamera, Scene, WebGLRenderer 
} from 'three'
import { SceneUtils } from 'three/examples/jsm/utils/SceneUtils'
import stats from '../utils/stats'
import { TrackballControls } from 'three/examples/jsm/controls/TrackballControls'
import dat from 'dat.gui'

const scene = new Scene()
// scene.overrideMaterial = new MeshDepthMaterial()

// WebGL
const webGLrenderer = new WebGLRenderer({ antialias: true })
webGLrenderer.setClearColor(0x000000)
webGLrenderer.setPixelRatio(window.devicePixelRatio)
webGLrenderer.setSize(window.innerWidth, window.innerHeight)
webGLrenderer.shadowMap.enabled = true
document.body.appendChild(webGLrenderer.domElement)

// Camera
// 处于相机 near 与 far 之间的物体，随着距离决定高度与消失情况
const camera = new PerspectiveCamera(45, window.innerWidth/window.innerHeight, 20, 1000)
camera.position.set(-50, 40, 50)
camera.lookAt(scene.position)

const controls = new function() {
  this.cameraNear = camera.near
  this.cameraFar = camera.far
  this.rotationSpeed = 0.02
  this.color = 0x00ff00
  this.numberOfObjects = scene.children.length

  this.addCube = function() {
    let cubeSize = Math.ceil(3 + Math.random() * 3)
    let cubeGeometry = new BoxGeometry(cubeSize, cubeSize, cubeSize)
    // let cubeMaterial = new MeshLambertMaterial({
    //   color: Math.random() * 0xffffff
    // })
    let cubeMaterial = new MeshDepthMaterial()
    let colorMaterial = new MeshBasicMaterial({
      color: controls.color,
      transparent: true,
      blending: MultiplyBlending
    })
    let cube = SceneUtils.createMultiMaterialObject(cubeGeometry, [colorMaterial, cubeMaterial])
    // let cube = new Mesh(cubeGeometry, colorMaterial)
    cube.castShadow = true

    cube.position.x = -60 + Math.round(Math.random() * 100)
    cube.position.y = Math.round(Math.random() * 10)
    cube.position.z = -100 + Math.round(Math.random() * 150)

    scene.add(cube)
    this.numberOfObjects = scene.children.length
  }
}

for (let i = 0; i < 10; i++) {
  controls.addCube()
}

const gui = new dat.GUI()

gui.add(controls, 'rotationSpeed', 0, 0.5)
gui.add(controls, 'addCube')
gui.addColor(controls, 'color')
gui.add(controls, 'cameraNear', 0, 100).onChange(e => {
  camera.near = e
  camera.updateProjectionMatrix()
})
gui.add(controls, 'cameraFar', 50, 200).onChange(e => {
  camera.far = e
  camera.updateProjectionMatrix()
})

const trackballControls = new TrackballControls(camera, webGLrenderer.domElement)

function render() {
  stats.update()
  trackballControls.update()

  scene.traverse(e => {
    if (e instanceof Mesh) {
      e.rotation.x += controls.rotationSpeed
      e.rotation.y += controls.rotationSpeed
      e.rotation.z += controls.rotationSpeed
    }
  })

  requestAnimationFrame(render)
  webGLrenderer.render(scene, camera)
}

render()